package com.bluebench.bigul.domain;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import com.bluebench.bigul.domain.Element.Parameter;
import com.bluebench.bigul.exception.GraphicInitializationException;
import com.bluebench.bigul.service.processor.GenericProcessor;

public class StaticInvocation extends Invocation{
	
	private String methodName;

	public StaticInvocation() {
		this.setElementType(ElementType.INVOCATION);
	}
	
	/**
	 * Implement logic for invoking static method that return the object
	 * @throws ClassNotFoundException 
	 * @throws InstantiationException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws NoSuchMethodException 
	 * @throws IllegalArgumentException 
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 * @throws GraphicInitializationException 
	 */
	@Override
	public Object invoke() throws ClassNotFoundException, SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, GraphicInitializationException {
		String classname = getClassName();
		Class<?> classtype = Class.forName(classname);
		List<Parameter> parameters = getParameters();
		Class<?>[] parameterTypes = getParameterTypes(parameters);
		Object[] argValues = new Object[parameters.size()];
		Method method = null;
		Object returnObj=null;
		if(parameters!=null && (!parameters.isEmpty())){
			for(int i=0;i<parameters.size();i++){
				Parameter p = parameters.get(i);
				p.setProcessor(GenericProcessor.getInstance(GenericProcessor.PARAMETER_PROCESSOR));
				Object iTextParamObj = p.process();
				argValues[i] = iTextParamObj;
			}
			
			method = classtype.getDeclaredMethod(methodName,parameterTypes);
			returnObj = method.invoke(null,argValues);
			
		}else{
			method = classtype.getDeclaredMethod(methodName);
			returnObj = method.invoke(null);
			
		}		
		
		return returnObj;
	}
	
	private Class<?>[] getParameterTypes(List<Parameter> parameters) throws ClassNotFoundException{
		
		Class<?>[] paramclassArray = new Class<?>[parameters.size()]; 
		
		for(int i=0;i<parameters.size();i++){
			String type = parameters.get(i).getType();
			Types t=null;
			if(type==null){
				t = Types.getType("default");
			}else{
				t = Types.getType(type);
			}
			
			paramclassArray[i]=Class.forName(t.getClassName());
		}
		
		return paramclassArray;		
	}	

	public String getMethodName() {
		return methodName;
	}

	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}

}
